/**
 * Copyright (C) 2005-2009 Alfresco Software Limited.
 *
 * This file is part of the Spring Surf Extension project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.carbones.auth;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.extensions.surf.UserFactory;
import org.springframework.extensions.surf.site.AuthenticationUtil;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.extensions.surf.support.AlfrescoUserFactory;

/**
 * Responds to Login POSTs to allow the user to authenticate to the web site.
 * 
 * @author muzquiano
 * @author kevinr
 */
public class LoginPageController extends AbstractController
{
    /**
     * <p>A <code>UserFactory</code> is required to authenticate requests. It will be supplied by the Spring Framework
     * providing that the controller is configured correctly - it requires that a "userFactory" is set with an instance
     * of a <code>UserFactory</code>. The <code>ConfigBeanFactory</code> can be used to generate <code>UserFactory</code>
     * Spring Beans</p>
     */
    private UserFactory userFactory;
    
    /**
     * <p>This method is provided to allow the Spring framework to set a <code>UserFactory</code> required for authenticating
     * requests</p>
     * 
     * @param userFactory
     */
    public void setUserFactory(UserFactory userFactory)
    {
        this.userFactory = userFactory;
    }


    /* (non-Javadoc)
     * @see org.alfresco.web.framework.mvc.AbstractController#createModelAndView(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        request.setCharacterEncoding("UTF-8");
        
        String username = (String) request.getParameter("username");
        String password = (String) request.getParameter("password");
        String successPage = (String) request.getParameter("success");
        String failurePage = (String) request.getParameter("failure");
        
        boolean success = false;
        try
        {
            // check whether there is already a user logged in
            HttpSession session = request.getSession(false);
            // handle SSO which doesn't set a user until later
            if (session != null && request.getSession().getAttribute(UserFactory.SESSION_ATTRIBUTE_KEY_USER_ID) != null)
            {
                // destroy old session and log out the current user
                AuthenticationUtil.logout(request, response);
            }
            System.out.println("trying to authenticate the user factory...");
            // see if we can authenticate the user
            userFactory = new AlfrescoUserFactory();
            boolean authenticated = userFactory.authenticate(request, username, password);  
            System.out.println("done..");
            if (authenticated)
            {
                AuthenticationUtil.login(request, response, username, false);
                
                // mark the fact that we succeeded
                success = true;
            }
        }
        catch (Throwable err)
        {
            throw new ServletException(err);
        }
        System.out.println("no errors.." + success);
        // If they succeeded in logging in, redirect to the success page
        // Otherwise, redirect to the failure page
        if (success)
        {
            if (successPage != null)
            {
                response.sendRedirect(successPage);
            }
            else
            {
                response.sendRedirect(request.getContextPath());
            }
        }
        else
        {
            // invalidate the session to ensure any session ID cookies are no longer valid
            // as the auth has failed - mitigates session fixation attacks by ensuring that no
            // valid session IDs are created until after a successful user auth attempt
            request.getSession().invalidate();
            if (failurePage != null)
            {
                response.sendRedirect(failurePage);
            }
            else
            {
                response.sendRedirect(request.getContextPath());
            }
        }  
        return null;
    }
}